interface Config {
    api?:{get?:any,post?:any,put?:any,remove?:any,download?:any,upload?:any,simulateUpload?:any}
    headers?:any
    trans?:() => []
}

/**
 * fetch(url, { method: "POST", headers, body: isPlainObject(data) ? JSON.stringify(data) : data })
            .then(async (response) => {
              const ok = response.ok;
              let res = await response.text()
              res = toJSON(res);
              if (!ok) {
                // ElMessage.warning(res)
                reject(res)
              }
              else {
                resolve(res)
              }
            })
            .catch(e => reject(e))
        })
 */

const http = (url:string,options:any,call?:any) => {
    return new Promise((resolve,reject) => {
        fetch(url,options).then(async resp => {
            let result:any;
            if(call){
                result = await call(resp);
                resolve(result)
                return ;
            }
            try {
                result = await resp.json()
            } catch (error) {
                result = await resp.text();
            }
            //
            resp.ok ? resolve(result) : reject(result)
        })
    })
}

const http2 = (f:any,args:any[],trans:any) => {
    let as = args;
    if(trans){
        as = trans(args);
    }
    f.apply(this,args)
}

export class Api {

    constructor(config:Config){
        const {api,headers,trans} = config;
        if(api){
            this.newApi = api;
        }
        if(headers){
            this.headers = headers;
        }
        if(trans){
            this.trans = trans;
        }
    }
    newApi:Partial<Api>
    headers:any = {"content-type":"application/json; charset=utf-8"}
    trans:() => []
    //
    get(url:string,options?:any,call?:any){
        if(this.newApi.get){
            http2.call(this.newApi,this.newApi.get,[url,options],this.trans)
        }else{
            http(url,Object.assign({headers:this.headers,method:"GET"},options),call)
        }
    }

    post(url:string,options?:any,call?:any){
        if(this.newApi.post){
            http2.call(this.newApi,this.newApi.post,[url,options],this.trans)
        }else{
            http(url,Object.assign({headers:this.headers,method:"POST"},options),call)
        }
    }

    put(url:string,options?:any,call?:any){
        if(this.newApi.put){
            http2.call(this.newApi,this.newApi.put,[url,options],this.trans)
        }else{
            http(url,Object.assign({headers:this.headers,method:"PUT"},options),call)
        }
    }

    remove(url:string,options?:any,call?:any){
        if(this.newApi.put){
            http2.call(this.newApi,this.newApi.remove,[url,options],this.trans)
        }else{
            http(url,Object.assign({headers:this.headers,method:"DELETE"},options),call)
        }
    }

    // 下载文件封装 可以通过参数来选择是否使用简单下载 ( a 标签)，还是接口下载 (数据流)
    download (){}

    // 上传的封装，包含 创建 input ，触发选择文件，然后处理文件，接着调用上传接口
    upload (){}

    // 模拟上传，获取文件数据
    simulateUpload (){}

    //

}